home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 6
/
FM Towns Free Software Collection 6.iso
/
t_os
/
chtiff
/
source
/
chtiff3.c
< prev
next >
Wrap
Text File
|
1993-07-08
|
15KB
|
669 lines
/* TIFFの変換をサポートする関数群
8ビットからxビットへ膨らます関数。*/
#include<stdio.h>
#include<stdlib.h>
#include"define.h"
#define EXCHANGE_SECTION 1
#include"function.h"
/* 8ビットタイル表示用 */
unsigned char diffuse( unsigned int x, unsigned int y,
unsigned short r, unsigned short g, unsigned short b )
{
unsigned char ret;
/* 上位3ビットが全て1ではなく、タイル化する点の時 */
if( ( r>>5 != 7 )&&( (x+y)&1 )&&( r&0x10 ) )
ret = (r&0xe0)+0x20;
else ret = (r&0xe0);
if( ( g>>5 != 7 )&&( (x+y)&1 )&&( g&0x10 ) )
ret |= ((g&0xe0)+0x20)>>3;
else ret |= ((g&0xe0) )>>3;
/* 青は2ビットしかないので、4ドットを使ったタイル表示となる */
switch( (b>>4)&3 ){
case 0:
ret |= b>>6;
break;
case 1:
if( (b>>6 != 3)&&(y%2)&&(x%2) )
ret |= (b>>6)+1;
else ret |= (b>>6);
break;
case 2:
if( (b>>6 !=3)&&( (x+y)%2 ) )
ret|= (b>>6)+1;
else ret|= (b>>6);
break;
case 3:
if( (b>>6 != 3)&&( y%2 || x%2 ) )
ret |= (b>>6)+1;
else ret |= (b>>6);
}
return( ret );
}
/* タイル表示時のパレット作成 */
void make_palet( void )
{
unsigned int i,j;
to.RED = MALLOC( 512 );
to.GREEN = MALLOC( 512 );
to.BLUE = MALLOC( 512 );
for( i=0; i<256; i++ ){
j = i&0xe0;
*(to.RED +i) = j<<8 | j<<5 | j<<2 | j>>1 | j>>4;
j = i&0x1c;
*(to.GREEN+i) = j<<11 | j<<8 | j<<5 | j<<2 | j>>1;
j = i & 0x03;
*(to.BLUE +i) = j<<14 | j<<12 | j<<10 | j<<8 | j<<6 | j<<4 | j<<2 | j;
}
}
/*
このプログラムでは唯一パレットを使うモードです。
関数read_IFDでパレットを読み込み、short from.RED[],from.GREEN[],from.BLUE[]
に各16ビットで色情報が記載されてます。
よって、様々な変換はこのパレット情報を加工して行います。
*/
void change8(int EXPAND)
{
unsigned short w,r,x,R,G,B;
puts("8Bit 画像データ変換を開始します。");
x = 0;
*to.Strip_Offset=ftell(to.fp);
switch(to.Bits_Per_Sample){
case 24:
while(1){
if( 256==(r=read_Gdata()) ) break;
R = *(from.RED + r)>>8;
G = *(from.GREEN + r)>>8;
B = *(from.BLUE + r)>>8;
write_Gdata( R ); /* REDと言えばRED5*/
write_Gdata( G ); /* GREEN */
write_Gdata( B ); /* BLUE */
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( R );
write_Gdata( G );
write_Gdata( B );
}
if( x >= from.Image_Width ) x = 0;
}
};
write_Gdata(256);
break;
case 16:
while(1){
if( 256==(r=read_Gdata()) ) break;
w = ( (*(from.GREEN+r) & 0xf800) >> 1 )
|( (*(from.RED +r) & 0xf800) >> 6 )
|( (*(from.BLUE +r) & 0xf800) >> 11);
write_Gdata( w & 0xff );
write_Gdata( w>>8 );
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( w & 0xff );
write_Gdata( w>>8 );
}
if( x >= from.Image_Width ) x = 0;
}
}
write_Gdata(256);
break;
case 8:
while( 256 != ( r=read_Gdata() ) ){
write_Gdata( r );
if( EXPAND ){
if( (++x) % 3 == 0 ) write_Gdata( r );
if( x >= from.Image_Width ) x = 0;
}
}
write_Gdata(256);
to.RED = from.RED;
to.GREEN = from.GREEN;
to.BLUE = from.BLUE;
break;
default:
puts("この変換には対応してません。");
return;
}
puts("画像データ変換を終了しました。");
return;
}
/*
Towns独自仕様16ビットです。16ビットの内訳をかきます。
一番左のビットはスーパーインポーズビットと呼ばれ、よく分かりません。
(現在の対応では、16→16以外の変換では、無条件に0にしてます。)
残り15ビットは、5ビットずつ左からGRBの順に色データがあります。
各ピクセルは16ビットで一個ですから、short型で書き込むわけです。
Townsはi80386CPUですから、上下バイトが入れ代わります。
さらに、NeXTのOpacity の関係で16bit になってるやつもついでに変換します。
*/
void change16(int EXPAND)
{
unsigned short w, r, r2, x, xx, y, b1, b2, R, G, B;
puts("16Bit 画像データ変換を開始します。");
x = 0;
*to.Strip_Offset=ftell(to.fp);
if( from.Opacity ) goto RGBO;
switch(to.Bits_Per_Sample){
case 24:
while(1){
if( 256==(r2=read_Gdata()) ) break;
r = read_Gdata();
write_Gdata( (((r&0x3)<<6)|((r2&0xe0)>>2)) ); /* Red 5bits */
write_Gdata( (r&0x7c)<<1 ); /* Green */
write_Gdata( (r2&0x1f)<<3 ); /* Blue */
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( (((r&0x3)<<6)|((r2&0xe0)>>2)) );
write_Gdata( (r&0x7c)<<1 );
write_Gdata( (r2&0x1f)<<3 );
}
if( x >= from.Image_Width ) x = 0;
}
};
write_Gdata(256);
break;
case 16:
r = 1;
while(1){
if( 256 == (r = read_Gdata()) ) break;
r2 = read_Gdata();
write_Gdata( r );
write_Gdata( r2 );
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( r );
write_Gdata( r2 );
}
if( x >= from.Image_Width ) x = 0;
}
}
write_Gdata(256);
break;
case 8:
y = 0;
while(1){
x = 0;
for( xx=0; xx<from.Image_Width; xx++){
if( 256==(r2=read_Gdata()) ) break;
r = read_Gdata();
R = ((r&0x3)<<6)|((r2&0xe0)>>2); /* Red 5bits */
G = (r&0x7c)<<1; /* Green */
B = (r2&0x1f)<<3; /* Blue */
write_Gdata( diffuse( x, y, R, G, B ) );
x++;
if( (EXPAND)&&(xx%3 == 2) ){
write_Gdata( diffuse( x, y, R, G, B ) );
x++;
}
}
if( r2 == 256 ) break;
y++;
}
write_Gdata(256);
make_palet();
break;
default:
puts("この変換には対応してません。");
return;
}
puts("画像データ変換を終了しました。");
return;
RGBO: /* ううぅぅ・・・こんなフォーマットがあろうとは・・・ */
switch(to.Bits_Per_Sample){
case 24:
while( 256 != (b1=read_Gdata()) ){
b2 = read_Gdata();
R = b1 & 0xf0; R |= (R>>4);
G = b1 & 0xf; G |= (G<<4);
B = b2 & 0xf0; B |= (B>>4);
write_Gdata( R ); /* RED5(しつこい!) */
write_Gdata( G ); /* GREEN */
write_Gdata( B ); /* BLUE */
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( R );
write_Gdata( G );
write_Gdata( B );
}
if( x >= from.Image_Width ) x = 0;
}
}
write_Gdata(256); /* 出力終了 */
break;
case 16:
w = from.Image_Width;
while( 256 != (b1=read_Gdata()) ){
b2 = read_Gdata();
R = b1 & 0xf0; R |= (G>>4);
G = b1 & 0xf; G |= (G<<4);
B = b2 & 0xf0; B |= (B>>4);
b1 = ( (R & 0xf8)<<2 ) | ( (G & 0xf8)<<7 ) | ( (B & 0xf8)>>3 );
write_Gdata( b1 & 0xff );
write_Gdata( b1 >> 8 );
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( b1 & 0xff );
write_Gdata( b1 >> 8 );
}
if( x >= from.Image_Width ) x = 0;
}
}
write_Gdata(256); /* 出力終了 */
break;
case 8:
y = 0;
while(1){
for( x=0; x<from.Image_Width; x++){
if( 256==(b1=read_Gdata()) ) break;
b2 = read_Gdata();
R = b1 & 0xf0;
G = (b1 & 0xf)<<4;
B = b2 & 0xf0;
w = diffuse( x, y, R, G, B );
write_Gdata( w );
if( (EXPAND)&&(xx%3 == 2) ) write_Gdata( w );
}
if( b1 == 256 ) break;
y++;
}
write_Gdata(256);
make_palet();
break;
default:
puts("この変換には対応してません。");
return;
}
puts("画像データ変換を終了しました。");
return;
}
/*
TIFF 5.0 でフルカラーとされている24ビットモードです。
連続する3バイトが1ピクセルで、RGBの順で各8ビットが割り振られており、
モトローラ・インテルの差もなく、一番扱いやすいデータです。
*/
void change24(int EXPAND)
{
unsigned short w, r, g, b, x, xx, y;
puts("24Bit 画像データ変換を開始します。");
x = 0; /* 今横座標のどこを書き込んでるのか */
*to.Strip_Offset=ftell(to.fp);
switch(to.Bits_Per_Sample){
case 24:
r = 1;
while(1){
write_Gdata( r = read_Gdata() );
if( r == 256 ) break;
write_Gdata( g = read_Gdata() );
write_Gdata( b = read_Gdata() );
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( r );
write_Gdata( g );
write_Gdata( b );
}
if( x >= from.Image_Width ) x = 0;
}
}
break;
case 16:
while(1){
if( 256==(r=read_Gdata()) ) break;
g = read_Gdata() & 0xf8;
b = read_Gdata() & 0xf8;
w = ( (r & 0x00f8) << 2 ) | ( g << 7 ) | ( b >> 3 );
write_Gdata( w & 0xff );
write_Gdata( w>>8 );
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( w & 0xff );
write_Gdata( w>>8 );
}
if( x >= from.Image_Width ) x = 0;
}
}
write_Gdata(256);
break;
case 8:
y = 0;
while(1){
x = 0;
for( xx=0; xx<from.Image_Width; xx++){
if( 256==(r=read_Gdata()) ) break;
g = read_Gdata();
b = read_Gdata();
write_Gdata( diffuse( x, y, r, g, b ) );
x++;
if( (EXPAND)&&(xx%3 == 2) ){
write_Gdata( diffuse( x, y, r, g, b ) );
x++;
}
}
if( r==256 ) break;
y++;
}
write_Gdata(256);
make_palet();
break;
default:
puts("この変換には対応してません。");
return;
}
puts("画像データ変換を終了しました。");
return;
}
/*
NeXTの標準、12ビットフォーマットです。これも独自使用だとは思います。
画像の幅が、奇数か偶数かで処理が違うので、その分遅くなるかも・・・
*/
void change12(int EXPAND)
{
unsigned short w,b1,b2,r,g,b,x,xx,y;
/*
r,g,b:いわずと知れたRGB成分
w :今、出力画像ラインのどこを処理してるかのカウンタ
x :今、入力画像ラインのどこを処理してるかのカウンタ
b1,b2: byte1 byte2
*/
puts("12Bit 画像データ変換を開始します。");
x = 0;
*to.Strip_Offset = ftell(to.fp);
switch(to.Bits_Per_Sample){
case 24:
w = from.Image_Width;
while( 256 != (b1=read_Gdata()) ){
b2 = read_Gdata();
/* 奇数ピクセルの書き込み */
r = b1 & 0xf0; r |= (r>>4);
g = b1 & 0xf; g |= (g<<4);
b = b2 & 0xf0; b |= (b>>4);
write_Gdata( r ); /* RED5(しつこい!) */
write_Gdata( g ); /* GREEN */
write_Gdata( b ); /* BLUE */
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( r );
write_Gdata( g );
write_Gdata( b );
}
if( x >= from.Image_Width ) x = 0;
}
/* 偶数ピクセルの書き込み */
if( w != 1 ){ /* 各ラインの最終ピクセルかどうか */
b1 = read_Gdata();
r = b2 & 0xf; r |= (r<<4);
g = b1 & 0xf0; g |= (g>>4);
b = b1 & 0xf; b |= (b<<4);
write_Gdata( r ); /* RED5(しつこい!) */
write_Gdata( g ); /* GREEN */
write_Gdata( b ); /* BLUE */
w -= 2;
if( w == 0 ) w = to.Image_Width;
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( r );
write_Gdata( g );
write_Gdata( b );
}
if( x >= from.Image_Width ) x = 0;
}
}
else w = from.Image_Width;
}
write_Gdata(256); /* 出力終了 */
break;
case 16:
w = from.Image_Width;
while( 256 != (b1=read_Gdata()) ){
b2 = read_Gdata();
/* 奇数ピクセルの書き込み */
r = b1 & 0xf0; r |= (r>>4);
g = b1 & 0xf; g |= (g<<4);
b = b2 & 0xf0; b |= (b>>4);
b1 = ( (r & 0xf8)<<2 ) | ( (g & 0xf8)<<7 ) | ( (b & 0xf8)>>3 );
write_Gdata( b1 & 0xff );
write_Gdata( b1 >> 8 );
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( b1 & 0xff );
write_Gdata( b1 >> 8 );
}
if( x >= from.Image_Width ) x = 0;
}
/* 偶数ピクセルの書き込み */
if( w != 1 ){ /* 各ラインの最終ピクセルかどうか */
b1 = read_Gdata();
r = b2 & 0xf; r |= (r<<4);
g = b1 & 0xf0; g |= (g>>4);
b = b1 & 0xf; b |= (b<<4);
b1 = ( (r & 0xf8)<<2 ) | ( (g & 0xf8)<<7 ) | ( (b & 0xf8)>>3 );
write_Gdata( b1 & 0xff );
write_Gdata( b1 >> 8 );
w -= 2;
if( w == 0 ) w = to.Image_Width;
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( b1 & 0xff );
write_Gdata( b1 >> 8 );
}
if( x >= from.Image_Width ) x = 0;
}
}
else w = from.Image_Width;
}
write_Gdata(256); /* 出力終了 */
break;
case 8:
y = 0;
while(1){
x = 0;
for( xx=0; xx<from.Image_Width; xx+=2 ){
if( 256 == (b1=read_Gdata()) ) break;
b2 = read_Gdata();
/* 奇数ピクセルの書き込み */
r = b1 & 0xf0;
g = (b1 & 0xf)<<4;
b = b2 & 0xf0;
write_Gdata( diffuse( x, y, r, g, b ) );
x++;
if( EXPAND&&(xx%3 == 2) ){
write_Gdata( diffuse( x, y, r, g, b ) );
x++;
}
/* 偶数ピクセルの書き込み */
if( from.Image_Width-xx != 1 ){ /* ラインの最終ピクセルか */
b1 = read_Gdata();
r = (b2 & 0xf)<<4;
g = b1 & 0xf0;
b = (b1 & 0xf)<<4;
write_Gdata( diffuse( x, y, r, g, b ) );
x++;
if( EXPAND&&(xx%3 == 0) ){
write_Gdata( diffuse( x, y, r, g, b ) );
x++;
}
}
}
if( b1 == 256 ) break;
y++;
}
write_Gdata(256);
make_palet();
break;
default:
puts("この変換には対応してません。");
return;
}
puts("画像データ変換を終了しました。");
return;
}
/*
TIFF 5.0 でフルカラーとされている24ビットモードに、不透明度を加えたやつです。
*/
void change32(int EXPAND)
{
unsigned short w,r,g,b,x,xx,y;
puts("32Bit 画像データ変換を開始します。");
x = 0; /* 今横座標のどこを書き込んでるのか */
*to.Strip_Offset=ftell(to.fp);
switch(to.Bits_Per_Sample){
case 24:
r = 1;
while(1){
write_Gdata( r = read_Gdata() );
if( r == 256 ) break;
write_Gdata( g = read_Gdata() );
write_Gdata( b = read_Gdata() );
read_Gdata(); /* Opacity 空読み */
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( r );
write_Gdata( g );
write_Gdata( b );
}
if( x >= from.Image_Width ) x = 0;
}
}
break;
case 16:
while(1){
if( 256==(r=read_Gdata()) ) break;
g = read_Gdata() & 0xf8;
b = read_Gdata() & 0xf8;
read_Gdata(); /* Opacity 空読み */
w = ( (r & 0x00f8) << 2 ) | ( g << 7 ) | ( b >> 3 );
write_Gdata( w & 0xff );
write_Gdata( w>>8 );
if( EXPAND ){
if( (++x) % 3 == 0 ){
write_Gdata( w & 0xff );
write_Gdata( w>>8 );
}
if( x >= from.Image_Width ) x = 0;
}
}
write_Gdata(256);
break;
case 8:
y = 0;
while(1){
x = 0;
for( xx=0; xx<from.Image_Width; xx++){
if( 256==(r=read_Gdata()) ) break;
g = read_Gdata();
b = read_Gdata();
read_Gdata(); /* Opacity 空読み */
write_Gdata( diffuse( x, y, r, g, b ) );
x++;
if( (EXPAND)&&(xx%3 == 2) ){
write_Gdata( diffuse( x, y, r, g, b ) );
x++;
}
}
if( r==256 ) break;
y++;
}
write_Gdata(256);
make_palet();
break;
default:
puts("この変換には対応してません。");
return;
}
puts("画像データ変換を終了しました。");
return;
}